import axios, {AxiosInstance, type AxiosRequestConfig, type AxiosRequestHeaders,} from "axios";

// ############### 请求 ####################
// 自定义请求配置
interface CustomRequestConfig {
  // 是否显示loading。默认值false
  showLoading?: boolean | (() => boolean);
  // 显示loading的函数。默认无动作
  showLoadingFunction?: () => void;
  // 隐藏loading的函数。默认无动作
  hideLoadingFunction?: (isSuccess: boolean) => void;

  // 添加请求头前的钩子函数。默认无动作
  beforeAddRequestHeaders?: (requestConfig: InternalRequestConfig) => void;
  // 添加请求头的钩子函数。默认无动作
  addRequestHeaders?: (headers: AxiosRequestHeaders) => void;
  // 添加请求头后的钩子函数。默认无动作
  afterAddRequestHeaders?: (requestConfig: InternalRequestConfig) => void;

  // 请求是否成功。参数为服务器响应，默认值true
  isServerSuccess?: boolean | ((serverResponse: any) => boolean);
  // 是否是token无效请求。默认值false
  isTokenInvalid?: boolean | ((serverResponse: any) => boolean);
  // 处理token无效的动作。默认无动作
  handleTokenInvalid?: () => void;
  // 是否传递完整响应。true传递AxiosResponse，false传递AxiosResponse.data，即服务器响应。默认值：false
  passFullResponse?: boolean;

  // 成功消息。默认值：serverResponse.msg
  successMsg?: (serverResponse: any) => string;
  // 是否显示成功消息。默认值false
  showSuccessMsg?: boolean | (() => boolean);
  // 显示成功消息的函数。默认无动作
  showSuccessMsgFunction?: (msg: string) => void;

  // 失败消息。默认值：serverResponse.msg
  failureMsg?: (serverResponse: any) => string;
  // 是否显示失败消息。默认值false
  showFailureMsg?: boolean | (() => boolean);
  // 显示失败消息的函数。默认无动作
  showFailureMsgFunction?: (msg: string) => void;
}

// 自定义请求默认配置对象
const defaultCustomRequestConfig: Required<CustomRequestConfig> = {
  showLoading: false,
  showLoadingFunction() {},
  hideLoadingFunction() {},

  beforeAddRequestHeaders() {},
  addRequestHeaders() {},
  afterAddRequestHeaders() {},

  isServerSuccess: true,
  isTokenInvalid: false,
  handleTokenInvalid() {},
  passFullResponse: false,

  successMsg(serverResponse) {
    return serverResponse.msg;
  },
  showSuccessMsg: false,
  showSuccessMsgFunction() {},

  failureMsg(serverResponse) {
    return serverResponse.msg;
  },
  showFailureMsg: true,
  showFailureMsgFunction() {},
};

// ############### Mock ####################
enum MockMode {
  // 正常请求服务器
  SERVER = "server",
  // 请求被mock
  MOCKER = "mocker",
  // 混合模式。此模式可实现部分请求被mock，也可以实现SERVER、MOCKER的效果
  MIX = "mix",
}

enum MockerStyle {
  // mock数据从服务器获取
  SERVER = "server",
  // mock数据从mockjs数据模板定义生成
  TEMPLATE = "template",
}

type MockerTarget = string | (() => string);
type MockerTemplate = string | object | (() => string | object);

type UrlConfigItem = {
  // 用于请求的服务器 API 接口 URL。完全匹配
  url: string;
  // 无默认值
  mock?: boolean | ((url: string) => boolean);
  // 无默认值
  mockerTarget?: MockerTarget;
  // 无默认值
  mockerTemplate?: MockerTemplate;
};
type UrlConfigItemArr = string[] | UrlConfigItem[];

// mock配置
interface MockConfig {
  // mock模式。默认值SERVER
  mode: MockMode;
  // 请求是否被mock默认值。默认值为false
  defaultMock?: boolean | ((url: string) => boolean);
  // Mocker服务器地址默认值
  defaultMockerTarget?: MockerTarget;
  // Mocker模版数据默认值
  defaultMockerTemplate?: MockerTemplate;
  // 细粒度的url配置。默认为空
  urlConfig?: UrlConfigItemArr;
}

// mock默认配置对象
const defaultMockConfig: Required<MockConfig> = {
  mode: MockMode.SERVER,
  defaultMock: false,
  defaultMockerTarget: null,
  defaultMockerTemplate: null,
  urlConfig: [],
};

// ############### AppRequest API ####################
// 创建AppRequest时使用的请求配置
type RequestConfig<D> = AxiosRequestConfig<D> & CustomRequestConfig;

// AppRequest内部使用的请求配置
type InternalRequestConfig = axios.InternalAxiosRequestConfig &
    Required<CustomRequestConfig>;

// AppRequest接口
interface AppRequestInterface {
  axiosInstance: AxiosInstance;

  requestConfig: InternalRequestConfig;

  mockConfig: Required<MockConfig>;
}

export {
  defaultCustomRequestConfig,
  defaultMockConfig,
  RequestConfig,
  InternalRequestConfig,
  AppRequestInterface,
  MockMode,
  MockerStyle,
  MockConfig,
};
